#pragma once

#include <signal.h>    // for signal()
#include <unistd.h>    // for fork(), chdir(), dup2(), setsid()
#include <sys/types.h> // for fork()
#include <stdlib.h>    // for exit()
#include <sys/stat.h>  // for open()
#include <fcntl.h>     // for open()

static const char *changedir = "/";
static const char *dev_null_path = "/dev/null";

void Deamon(bool ischangedir, bool isclosefd)
{
    // 1. ignore signals which might cause the exit of the process by excepions
    signal(SIGCHLD, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    // 2. create a new process, and exit the parent process, make child to become a session leader
    if (fork() > 0)
    {
        // father process exit
        exit(0);
    }
    // 3. set the child process as a session leader
    setsid();
    // 4. change the current working directory to root
    if (ischangedir)
    {
        chdir(changedir);
    }
    // 5. redirect the standard input, output, and error to /dev/null
    if (isclosefd)
    {
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
    }
    else
    {
        int fd = open(dev_null_path, O_RDWR);
        if (fd > 0)
        {
            dup2(fd, STDIN_FILENO);
            dup2(fd, STDOUT_FILENO);
            dup2(fd, STDERR_FILENO);
            close(fd);
        }
    }
}